package com.och.mrcp.handler;

import com.och.mrcp.core.sip.model.SipMessage;
import com.och.mrcp.core.sip.model.SipRequest;
import com.och.mrcp.core.sip.model.SipResponse;
import com.och.mrcp.core.sip.transaction.SipTransaction;
import com.och.mrcp.core.sip.transaction.SipTransactionManager;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;

@Slf4j
public abstract class SipMessageProcessor {
    
    protected final SipTransactionManager transactionManager;
    
    protected SipMessageProcessor(SipTransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }
    
    public abstract void processMessage(SipMessage message, InetSocketAddress sender);
    
    protected void handleSipRequest(SipRequest request, InetSocketAddress sender) {
        log.info("Handling SIP request: {} {}", request.getMethod(), request.getRequestUri());
        
        try {
            // 创建服务器事务
            SipTransaction.Type transactionType = determineTransactionType(request);
            SipTransaction transaction = transactionManager.createServerTransaction(request, transactionType);
            
            // 根据请求方法处理
            switch (request.getMethod()) {
                case "INVITE":
                    handleInviteRequest(request, sender, transaction);
                    break;
                case "ACK":
                    handleAckRequest(request, sender, transaction);
                    break;
                case "BYE":
                    handleByeRequest(request, sender, transaction);
                    break;
                case "CANCEL":
                    handleCancelRequest(request, sender, transaction);
                    break;
                case "OPTIONS":
                    handleOptionsRequest(request, sender, transaction);
                    break;
                case "REGISTER":
                    handleRegisterRequest(request, sender, transaction);
                    break;
                default:
                    handleUnknownRequest(request, sender, transaction);
                    break;
            }
            
        } catch (Exception e) {
            log.error("Error handling SIP request: {}", e.getMessage(), e);
            sendErrorResponse(sender, e);
        }
    }
    
    protected void handleSipResponse(SipResponse response, InetSocketAddress sender) {
        log.info("Handling SIP response: {} {}", response.getStatusCode(), response.getReasonPhrase());
        
        try {
            // 查找对应的事务
            SipTransaction transaction = transactionManager.findTransactionByResponse(response);
            if (transaction != null) {
                if (response.isProvisional()) {
                    transaction.setProvisionalResponse(response);
                } else {
                    transaction.setFinalResponse(response);
                }
                transactionManager.updateTransaction(transaction);
            } else {
                log.warn("No transaction found for response: {}", response);
            }
            
        } catch (Exception e) {
            log.error("Error handling SIP response: {}", e.getMessage(), e);
        }
    }
    
    private SipTransaction.Type determineTransactionType(SipRequest request) {
        if ("INVITE".equals(request.getMethod())) {
            return SipTransaction.Type.INVITE_SERVER;
        } else {
            return SipTransaction.Type.NON_INVITE_SERVER;
        }
    }
    
    protected abstract void handleInviteRequest(SipRequest request, InetSocketAddress sender, SipTransaction transaction);
    protected abstract void handleAckRequest(SipRequest request, InetSocketAddress sender, SipTransaction transaction);
    protected abstract void handleByeRequest(SipRequest request, InetSocketAddress sender, SipTransaction transaction);
    protected abstract void handleCancelRequest(SipRequest request, InetSocketAddress sender, SipTransaction transaction);
    protected abstract void handleOptionsRequest(SipRequest request, InetSocketAddress sender, SipTransaction transaction);
    protected abstract void handleRegisterRequest(SipRequest request, InetSocketAddress sender, SipTransaction transaction);
    protected abstract void handleUnknownRequest(SipRequest request, InetSocketAddress sender, SipTransaction transaction);
    protected abstract void sendErrorResponse(InetSocketAddress recipient, Exception error);

    /**
     * 将响应发送给指定的远端。由具体处理器实现（TCP/UDP不同）。
     */
    protected void sendResponse(InetSocketAddress recipient, SipResponse response) {
        // 由具体的网络处理器（TCP/UDP）负责发送，这里提供缺省空实现以避免强制实现
    }
    
    protected void copyHeaders(SipRequest request, SipResponse response) {
        response.setCallId(request.getCallId());
        response.setCseq(request.getCseq());
        response.setFrom(request.getFrom());
        response.setTo(request.getTo());
        response.setVia(request.getVia());
    }
    
    protected String generateSdpResponse() {
        // 简单的SDP响应示例
        return "v=0\r\n" +
               "o=- 1234567890 1234567890 IN IP4 127.0.0.1\r\n" +
               "s=OCH MRCP Session\r\n" +
               "c=IN IP4 127.0.0.1\r\n" +
               "t=0 0\r\n" +
               "m=audio 10000 RTP/AVP 8\r\n" +
               "a=rtpmap:8 PCMA/8000\r\n";
    }
}
